﻿using System;
using System.Collections;
using System.Text;

namespace Eneta.Portal.Forum.Core.Domain.Entities
{
    public class Permission
    {
        private BitArray bitMask;

        public Permission()
        {
            bitMask = new BitArray(0x16, false);
        }

        public Permission(string permissionMask)
            : this()
        {
            if (permissionMask == null)
            {
                throw new ApplicationException("Cannot create a permission mask from nothing.");
            }
            if (permissionMask.Length == 0)
            {
                throw new ApplicationException("Cannot create a permission mask with an empty string.");
            }
            if (permissionMask.Length < 0x16)
            {
                throw new ApplicationException("Permission mask length is incorrect.");
            }
            for (var i = 0; i < permissionMask.Length; i++)
            {
                var ch = permissionMask[i];
                if ((ch < '0') || (ch > '1'))
                {
                    throw new ApplicationException(string.Format("Invalid character {0} (position {1}) in string {2} passed in for creation.", ch, i, permissionMask));
                }
                var permission = ch == '1';
                var right = (Rights)i;
                SetPermission(right, permission);
            }
        }

        public bool HasPermission(Rights right)
        {
            return bitMask.Get((int)right);
        }

        public void SetAllRights(bool permission)
        {
            for (int i = 0; i < 0x16; i++)
            {
                var right = (Rights)i;
                SetPermission(right, permission);
            }
        }

        public void SetPermission(Rights right, bool permission)
        {
            bitMask.Set((int)right, permission);
        }

        public override string ToString()
        {
            var builder = new StringBuilder();
            foreach (bool flag in bitMask)
            {
                builder.Append(Convert.ToByte(flag));
            }
            return builder.ToString();
        }

        // Properties
        public string DisplayString
        {
            get
            {
                var builder = new StringBuilder();
                for (var i = 0; i < 0x16; i++)
                {
                    var right = (Rights)i;
                    if (HasPermission(right))
                    {
                        builder.AppendFormat("{0} ", right);
                    }
                }
                return builder.ToString();
            }
        }

        // Nested Types
        public enum Rights
        {
            Read,
            Add,
            Edit,
            Reply,
            Delete,
            Sticky,
            Announcement,
            Polls,
            Vote,
            Moderate,
            Attach,
            Admin,
            PlaceHolder0,
            PlaceHolder1,
            PlaceHolder2,
            PlaceHolder3,
            PlaceHolder4,
            PlaceHolder5,
            PlaceHolder6,
            PlaceHolder7,
            PlaceHolder8,
            PlaceHolder9,
            LastRight
        }
    }
}
